Cursor commands





The cursor pseudo object, the most complex pseudo object supported by plt, consists of one or more markers and several uicontrols with complex interactions. Because of this you normally will not create cursor objects on your own, but will rely on plt to create them automatically when you specify the data to be plotted. However, it is possible to create a cursor object manually with the cursor init command described at the end of this section. For many casual plotting applications, the plt cursors will behave as desired out of the box. For more sophisticated applications you may want to modify the cursoring behavior using the plt parameters (DualCur, Xstring, Ystring, Options) or the independent cursor commands shown below.

DualCur parameter:

Normally the cursor value for only a single trace (referred to as the active trace) is shown in an edit box below the plot. However, sometimes it is convenient to show the y-value for two traces simultaneously. This is done by using the 'DualCur' parameter which specifies the trace to display its y-value on the screen (in addition to the display of the active trace). Try out the editz.m demo program which uses Dual Cursors to simultaneously display the magnitude and phase of a transfer function. (In fact, transfer function displays were the problem that inspired the Dual Cursor feature.) The alternate method of specifying the dual cursor trace (as an offset from the active trace) is indicated by using a negative number for the DualCur parameter. The demo program afilt.m demonstrates the use of that mode. The use of the DualCur mode is covered in more detail near the end of the cursoring guide found here:
Cursoring.

Xstring/Ystring/Zstring parameters:

The 'Xstring' and 'Ystring' plt arguments allow you to add text strings just to the right of the cursor X or Y readout values. Since these strings occupy the same screen area as the delta cursor readouts, they get covered up when you are in delta cursor mode (or if a zoom window is visible). However those are usually temporary modes, so as you will see, these strings still prove useful. Also, those are only the default positions for these strings. As you will see later, you can easily move these strings anywhere in the figure. The 'Zstring' parameter is similar except the default position for the string is near the center of the lower edge. This might overlap with the Xaxis label, so some repositioning might be required either of the Zstring parameter or the plot position (using the 'xy' parameter).
String Replacement value
@CID cursor ID
@XVAL active cursor X position
@YVAL active cursor Y position
@XY same as complex(@XVAL,@YVAL)
@IDX active cursor index
@HAND handle of active trace
@LNUM  line number of active trace
@Q1 getappdata(gcf,'Q1')
@Q2 getappdata(gcf,'Q2')
@Q3 getappdata(gcf,'Q3')
@Q4 getappdata(gcf,'Q4')
@V1 getappdata(gcf,'V1')
@V2 getappdata(gcf,'V2')
@V3 getappdata(gcf,'V3')
@V4 getappdata(gcf,'V4')

Most of the power of the Xstring and Ystring parameters stem from their string replacement feature described in this table. Strings in the first column of the table are replaced with the value shown in the second column.

@Q1 thru @Q4 can be used to provide additional arguments to the Xstring/Ystring/Zstring parameters. You can set a value to one of these arguments with a command such as setappdata(gcf,'V1',ArgValue), or as you will see in the examples below you can specify the value of the argument in the XYZ string by using its cell array form. (The latter is the most concise method in the situation where the argument value is known at the time the XYZ string is created and the argument value will not be modified.)

@V1 thru @V4 are similar except that they are assumed to be vector quantities and they must be followed by a parenthetical expression containing an index into the vector. For example, you can use something like @V1(4), or @V1(@IDX). If you have used up all the scalar quantities (Q1 thru Q4), you could put a scalar quantity into V1 (for example). Then you could access the scalar within an XYZstring by using @V1(1).

The replacement table to the right shows that @Q1 is replaced by getappdata(gcf,'Q1'). That is a simplification, in that it is actually replaced by plt('misc',21) which has the same effect as the getappdata command, but has the advantage that it will work in a multi-figure application even when the focus might be on a figure that does not contain the application data. (If the 'misc' command does not find the application data in the current figure it looks at all linked figures to find the data). Similarly, if you change the 21 in the 'misc' command to 22,23,24,11,12,13,14 it will retrieve the value for Q2,Q3,Q4,V1,V2,V3,V4 respectively.

Notes:

Xstring/Ystring Examples:

Suppose it was important to see the cursor index as well as the usual cursor x and y values (i.e. you want to know that you are looking at the sixty-fifth data element for instance). You could do this as follows:

plt(x,y,'xstring','sprintf("index = %d",@IDX)');

A string within a string (such as the 'index = %d' above) is normally written in Matlab using two consecutive single quote characters on both sides of the string. Since this can get verbose and confusing at times, callbacks defined within plt may use a double quote character instead of two successive single quotes. That's why the double quotes appear in the line above.

If the default color and position of the Xstring is not suitable, you could change them by using the cell array form, for example:

plt(x,y,'xstring',{'sprintf("index = %d",@IDX)' 'color' [1 0 0] 'pos' [x y]});

You could also include additional text string properties in this list such as 'FontSize' and 'FontName' for example. The easiest way to determine the [x y] position is to enter the plt reposition mode by right clicking the Δ button (or by typing plt move into the command window) and then drag the Xstring to the desired location with the mouse. Then the required [x y] position will be reported in the Matlab command window.

Although the mean of the active trace y values can be shown using one of the usual cursor features, suppose you wanted to display the mean of the entire data set (independent of the viewing window). Suppose also that you want to continuously display the y/x ratio. (This ratio is also a standard cursor feature, but it's not continuously visible.) You could accomplish both of those feats as follows:

plt(x,y,'xstring','sprintf("mean: %f",mean(get(@HAND,"y")))',...
        'ystring','prin("Y/X: %5w",@YVAL/@XVAL)');


Suppose your x axis is measured in seconds with a zero reference of 5pm, 21-Jan-2007 UTC. The cursor x-axis readout will be in seconds past the reference, but you may want an additional cursor readout that shows the actual time of day. This can be accomplished as follows:

plt(t,y,'xstring',...
  'sprintf("utc:%s",datestr(datenum("21-Jan-07 17:00")+@XVAL/86400,13))');


Note the 86400 (the number of seconds in a day) is needed because date numbers are measured in days. If your x axis unit was "weeks", you would replace /86400 with *7.  If you removed the ,13 near the end of the line (date string format), then the readout would show the complete date and time instead of just the time. Another way to code the statement above is:

plt(t,y,'xstring','sprintf("utc: %s",datestr(@Q1+@XVAL/86400,13))');
setappdata(gcf,'Q1',datenum(2007,1,21,17,0,0));


The second statement puts the reference time in a figure application data value which is used by plt when updating the Xstring. This method is much more convenient when the reference time can change. Note that the reference time is identical to that used above, although it's written in the vector format instead of the character format.

A more convenient way of writing the above command when the value of Q1 is not going to change is to use the cell array form as follows:

plt(t,y,'xstring',{'sprintf("utc: %s",datestr(@Q1+@XVAL/86400,13))' ...;
                   'Q1' datenum(2007,1,21,17,0,0) 'color' [1 1 0] 'fontsize' 12});


Sometimes the 1 second resolution provided by datestr is not sufficient. You can increase this resolution to 1 millisecond by using the date string function provided by plt as follows:

plt(t,y,'xstring','sprintf("utc: %s",plt("datestr",@Q1+@XVAL/86400,13))');

Occasionally its useful to use an edit box instead of a string for one or both of these customized cursor controls. (The pltn.m example does this for the Xstring, although the Ystring is still rendered as a text string.) To do that, simply insert a question mark before the string. The first example above is rewritten below to use an edit box.

plt(x,y,'xstring','?sprintf("index = %d",@IDX)');

See the following applications and demo programs, for more examples of the use of the Xstring/Ystring/Zstring parameters:
      math folder: airspeed, carlo, gpsLog
      sig folder: afiltALT, editz, erip

Cursor commands

Notes: The cid (cursor ID) that appears in all the commands shown below is an integer that identifies the cursor the command is to act on. This integer is returned from the cursor initialization command used to create the cursor. If an axis contains a cursor, its cid is saved in the axis user data. (The cid stored in the axis user data is always a scalar since an axis may only contain a single cursor object.) You can specify that the cid should be retrieved from the axis user data by specifying a zero for the cid. So for example the following two commands have the same effect:

cur(0,'visON')
cur(get(gca,'user'),'visON')
  Although cid is usually specified as a number, you may also specify it as a decimal character string. This allows many of the cursor function calls to use the Matlab command syntax. For example, these three lines have the same effect:

cur(1,'visON')
cur('1','visON')
cur 1 visON
  The figure 'cid' application data variable contains a vector with the cursor IDs for all the cursor objects in the figure. You can specify that the cid should be retrieved from this vector by supplying a negative number as the cid (for example -2 specifies the 2nd element of this vector). This means that the following two lines have the same effect:

xy=cur(-2,'get');
c=getappdata(gcf,'cid'); xy=cur(c(2),'get');
  All the following commands are case-sensitive (unlike all the other plt parameters previously described) and must use the exact case shown below.
  All the cursor commands below may return up to two arguments. If the return arguments are listed for a cursor command, the return values will be as specified. However if the return arguments are not listed for a particular command, the first return value (if requested) will be the active cursor handle and the second return value (if requested) will be the active line handle.
  See the following programs for examples of the use of the cursor commands described below:
      demo folder:   movbar, pltmap, pltn, pub2, trigplt
      math folder: airspeed, circles12, gauss, gpsLog, julia
      sig folder: afilt, editz, erip, fseries, weight
      util folder: pltwater

[xy k] = cur(cid,'get',n);
Get x and y coordinates of the cursor location the last time it was on trace #n. The trace number is optional - if it is not specified then the position of the active trace is returned. xy is a complex value. Its real part is the cursor x-coordinate and its imaginary part is the y coordinate. The second return value (if requested) is the index into the x data vector of the cursor position.

[n h] = cur(cid,'getActive');
Returns the line number of the active cursor. The second return value (if requested) is the handle of the active trace.

h = cur(cid,'obj');
Returns a 16-element vector of handles to the following cursor objects:
    1:  x label     5:  y cursor readout     09:  marker/linestyle button     13:  main (left) axis
    2:  y label     6:  y cursor expansion     10:  delta button     14:  right hand axis (0 if none)
    3:  x cursor readout     7:  peak button     11:  expansion box     15:  current cursor marker
    4:  x cursor expansion     8:  valley button     12:  delta cursor     16:  TraceID axis (0 if none)

u = cur(cid,'expHis');
Returns an array containing the display expansion history.
Each row contains one display expansion as [xmin, xmax, ymin, ymax, code] where:

cur(cid,'visON');
cur(cid,'visOFF');

Shows or hides the following objects:

Note that this function is invoked alternately (visOFF/visON) when you right-click on the plot y-axis label (which also hides/shows the menu box).

cur(cid,'aux','on');
cur(cid,'aux','off');

Shows or hides the auxiliary (dual) cursor and its edit box

cur(cid,'setObjPos',p);
Sets the cursor object positions to p, where p is a 9 by 4 element array. Each row contains (x,y,width,height) which represents the position and size of the following objects:

  1. x-axis edit box label
  2. y-axis edit box label
  3. x-axis edit box (cursor readout)
  4. x-axis cursor expansion edit box
  5. y-axis edit box (cursor readout)
  6. y-axis cursor expansion edit box
  7. peak button
  8. valley button
  9. delta cursor button

Note that this command does not set the position of the optional x-axis control slider. However you can set this position using the plt 'xy' parameter, or with a command such as:
set(findobj(gcf,'tag','xslider'),'position',p);

cur(cid,'xlim',p);
Set new x axis limits and update expansion history, where p=[xmin,xmax] Normally the action string ('xlim' in this case) is case insensitive, but for this command the case of the 'L' character is significant. If the L is lower case then the axis callback function is executed after the axis limits have been updated and if the L is upper case then the axis callback function is not executed. The case of the other characters in the action string are ignored (so 'xLim' and 'XLIM' are equivalent). This sensitivity to the case of the L character applies to the next two cursor commands described below as well ('yLim' and 'xyLim')

cur(cid,'ylim',p,pAux);
Set new y axis limits and update expansion history, where p=[ymin,ymax].
and optionally pAux=[ymin,ymax] (for the right hand axis).

cur(cid,'xylim',p,pAux);
Set new x and y axis limits and update expansion history, where p=[xmin,xmax,ymin,ymax].
and optionally pAux=[ymin,ymax] (for the right hand axis).

cur(cid,'exRestore',u);
Restores an expansion history previously saved in u.

cur(cid,'axisCB',fcn);
String fcn will be evaluated whenever an axis limit is changed. This cursor command overwrites any axis callback function entered using the 'axisCB' parameter on the plt command line. The rules for string substitutions and function handles are the same as mentioned below in the moveCB command.

cur(cid,'moveCB',fcn);
String fcn will be evaluated whenever the cursor is moved. Before the fcn string is evaluated all occurrences of  the strings in the 1st column of the table above ( @CID, @XVAL, @YVAL, @XY, @IDX, @HAND, @LNUM, etc,) are replaced with the values in the 2nd column of that table. fcn is not called by events initiated from outside the figure window containing the cursor. (For example, a button push that moves the cursor in another figure window would not activate the callback. This prevents infinite loops when figure A modifies figure B's cursor and visa versa.) If you do want to enable the callback for external events, insert an extra semicolon as the first character of the moveCB callback string. This cursor command overwrites any axis callback function entered using the 'moveCB' parameters on the plt command line. In addition to a string, fcn may also be a function handle of the form @func or {@func,arg1,arg2,...,argn}. Note that the string substitutions can't be used with the function handle form of this parameter. Also note that a similar callback is provided for the TraceID fields, although the string substitutions allowed are different than the ones mentioned above. See the 'TIDcback' parameter under Trace properties.

cur(cid,'moveCB2',fcn);
This call operates similarly to the set moveCB command shown above and the functions specified in both these calls are executed whenever the cursor is moved. However, normally you will not want to use this call because the moveCB2 function is used internally by plt to keep the CursorID tag (just to the left of the y-axis cursor readout) so that it always identifies the cursored trace name. It's also used by plt in the linked subplot mode to keep the plots in a column synchronized. In rare situations, you may wish to modify those behaviors, which you can do with the moveCB2 function.

cur(cid,'setActive',a,k);
Switches the active cursor to the line specified by  a (a must be an integer between 1 and the number of lines in the plot). The cursor will be placed at index k. If k (optional) is out of bounds or not supplied, then the cursor will be placed in the center of the array. When a is zero (a special case), the active line remains the same and only the cursor index is changed - which would have the same as calling the update command (below). Normally the cursor callback function will be called, but you can suppress the call to the callback by supplying the index (k) and setting it to the negative of the desired index location.

cur(cid,'update',k);
cur(cid,'updateH',k);
cur(cid,'updateN',k);

Moves the active cursor to index k in the data set and calls any user-defined cursor callbacks (moveCB, xstring, ystring). If k is out of bounds, the cursor is set to the middle of the array associated with the active trace. If you do not supply the argument k, then the command does not move the cursor, however, it does execute the cursor callbacks. If update moves the cursor to an area that is not inside the current axis limits, it will shift the axis limits to make the cursored data element visible. However when the cursor is moved by updateH the axis limits will never be adjusted. (Think of this as "Update, Hold".) Also updating the cursor with the updateN command has the same effect as using the updateH command except that the cursor callback function (defined by 'MoveCB') is not called like it is with the update and updateH commands.

When the index is not needed we can abbreviate the update command by omitting the 'update' string. This means that the following two lines are equivalent:
    cur(cid);
    cur(cid,'update');

We can abbreviate the update command even more by omitting the cursor ID which defaults to -1. This means that the following two lines are equivalent:
    cur;
    cur(-1);

And finally, there is one more variant of the update and updateH commands:
    cur(cid,'update',k,x,y);
    cur(cid,'updateH',k,x,y);

The moves the active cursor to the index k as above. Normally x and y would be the position of the kth element of the array associated with the active trace, in which case this command behaves the same as if you didn't include the last two parameters. However x and y can be any position on the axis, and the visible cursor marker will be moved to those coordinates. (It's rare to want to move the cursor off the line, but it may sometimes be useful.)

cur(cid,'updateS');
Updates the Xstring, Ystring, and Zstring text without moving the cursor or calling any other callback functions. This is most useful after modifying one of the @Q or @V variables that affect the contents of one or more of the XYZstrings.

cur(cid,'peakval',0); Moves the specified cursor to the next peak
cur(cid,'peakval',1); Moves the specified cursor to the next valley
cur(cid,'peakval',2); Moves the specified cursor to the highest peak
cur(cid,'peakval',3); Moves the specified cursor to the lowest valley
You can also use the command form of these commands. For example, if you are referring to cursor associated with the current axis, the 'lowest valley' command above could be written as cur 0 peakval 3;

cur(cid,'clear');
All the cursor objects are deleted.

cur(cid,'TraceIDs');
Returns a cell array containing the original TraceIDs associated with cursor cid. If the TraceIDs were modified (by using the plt('rename') command for example), those changes will not be seen with this cursor command. For example, when running the demo program afilt.m, if you click on the left hand plot and then type cur(0,'TraceIDs') or the command form cur 0 TraceIDs you will see:
    ans = 5x1 cell array
      {'Butter'}
      {'Bessel'}
      {'Cheby1'}
      {'Cheby2'}
      {'Elliptic'}


cur(cid,'Emode',mode);
Puts the cursor specified into the permanent erase mode specified by the case-insensitive string argument mode as follows:
mode action
'UpDown' Allows the edit cursor point to move only in the y-axis direction. Only the first character of the mode parameter is used, so 'UpDown' is equivalent to 'UD', or just 'u'. This command has a similar effect to right clicking on the last selection in the popup menu shown below (except that action toggles this persistent data editing mode on or off). See the Data editing section for details.)
'LeftRight' Allows the edit cursor point to move only in the x-axis direction. Equivalent to 'lr' or 'L' for example.
'Both' Allows the edit cursor point to move in both the x and y directions. Equivalent to 'B' or 'b' for example.
'Off' Turns off any persistent editing mode that was initiated by one of the above 'Emode' commands or that was initiated by right clicking any of the bottom three selections of the popup menu shown at the right. (Note: This is the popup that appears when you right click on the Ycursor edit box. Again, see the Data editing section for details.)

Equivalent to 'O' or 'o' for example.

See the editz.m, erip.m, and hermite.m applications for examples of the use of the cursor Emode commands.


plt hideCur;
Hides the cursor objects. (This has the same effect as right-clicking on the y-axis label). See cursoring.

plt hideTID;
Hides all the TraceID boxes in the current figure

Note: The following cursor commands were designed primarily for plt internal use, although sometimes they may also be useful in your programs. (These commands are case-sensitive.) The "0" in the first seven commands below refers to the current cursor. You may replace the "0" with the actual cursor ID number, or "-n" to refer to the nth cursor.

plt cleft 0 ZoomOut; Zoom out both x & y axis by 40%.
plt cright 0 ZoomOut;  
Zoom in both x & y axis by 40%. With the functional form (which applies to the command above as well), you may also include an additional argument that specifies the zoom ratio. For example, this command specifies a 20% ratio (half of the default amount): plt('cright',0,'ZoomOut',.2);

plt cleft 0 peakval 0; Move the cursor to the next peak. (The last argument may be omitted in this case.)
plt cleft 0 peakval 1; Move the cursor to the next valley
plt cleft 0 peakval 2; Reset the peak finder (i.e. move the cursor to the highest peak)
plt cleft 0 peakval 3; Reset the valley finder (i.e. move the cursor to the lowest valley)
plt cleft 0 TGLlogy; Toggle the y-axis between linear/log
plt cleft 0 TGLlogx; Toggle the x-axis between linear/log
plt cright 0 TGLlogy; Open Hardcopy menu
plt cright 0 TGLlogx; Swap x & y axes
plt cleft 0 markCB; Toggle the delta cursor mode on or off
plt cleft 0 mlsCB; 3-way toggle of all traces between markers only, lines only, and both lines & markers
plt cleft 0 mark; Adds a text label identifying the current cursor location
plt xleft TGLgrid; Toggle between grid lines and ticks
plt xright TGLgrid; Toggle between default and alternate grid style
plt xleft data; Open a cursor data window
plt xright data; Toggle the menu bar on/off
plt xleft mark 2; Open a window allowing editing plt figure colors
plt xleft mark 3; Write a file saving the current plt figure colors
plt xleft link; Toggle right hand axis link status
plt xleft RMS;
Equivalent to clicking on the cursorID tag which rotates between the five cursor modes [normal, Avg, RMS, y/x, sqrt(x^2+y^2)]. After five of these commands the cursor mode will be the same as it was before the first of those commands (having rotated thru all the modes).

plt xleft EDIT 1; Enter data editing (using last used editing mode)
plt xleft EDIT 2; Open up Yedit popup menu
plt xleft EDIT 5; Exit data editing mode
plt xleft Yedit 1; Open a window allowing editing the line properties of cursored trace. (The command plt xright mark;) also does the same thing.
plt xright Yedit 1; Open a window allowing editing the plt figure properties
plt xleft Yedit 2; Toggle multiCursor mode
plt xleft Yedit 3; Toggle xView slider
plt xleft Yedit 4; Cancel data editing mode
plt xleft Yedit 5; Enter data edit mode (Range)
plt xleft Yedit 6; Enter data edit mode (Range left/right)
plt xleft Yedit 7; Enter data edit mode (Range up/down)
plt xleft Yedit 8; Enter data edit mode (Modify)
plt xleft Yedit 9; Enter data edit mode (Modify left/right)
plt xleft Yedit 10; Enter data edit mode (Modify up/down)
plt xright Yedit 8; Toggle persistent data edit mode (Modify)
plt xright Yedit 9; Toggle persistent data edit mode (Modify left/right)
plt xright Yedit 10; Toggle persistent data edit mode (Modify up/down)

Mouse motion functions:

If you create a figure with a plt command that includes the parameter 'MotionZoom','funcname', then if you create a zoom box (see
The expansion box) while you are adjusting the size of the zoom box the function funcname([x1 x2 y1 y2]) will be continually called as the mouse is moved (i.e.  for as long as the mouse button is held down). The coordinate [x1 y1] is the position of the lower left corner of the zoom box and [x2 y2] is the coordinate of the upper right corner. It may require some imagination to see how using such a parameter would enhance your user interface. The example gauss.m (in the demo folder) demonstrates the use of the MotionZoom function, athough its use of the MotionZoom feature is somewhat contrived in that it was thrown in there to demonstrate the feature more than for any practical reason. The pltmap.m example (in the demo folder) also makes use of the MotionZoom feature, and in this case it does provide a useful benefit.

In place of the character string 'funcname' you may also use @funcname or to insert extra parameters to the function, use {@funcname param1 param2}. (The 4-element vector specifying the zoombox corners will be the 3rd parameter of the function in this example.) These alternate forms also apply to the other mouse motion functions

Including the parameter 'MotionZup','funcname' has a similar effect except that the function 'funcname' only is called when the mouse button is released. The MotionZoom and MotionZup functions are called when the zoom box is moved or resized as well as when it is first created.

You may also create, modify, or remove these mouse motion functions after the call to plt by modifying the corresponding application data variable associated an axis. For example, these commands will set the mouse motion functions as expected:
    setappdata(gca,'MotionZoom','funcA');
    setappdata(gca,'MotionZup',@funcB);

Three additional mouse motion functions (MotionEdit, EditStart, EditStop) may also be defined and are described in the Data Editing section.

Creating a cursor pseudo object:

Usually the cursor objects are initialized from the main plt() call that specifies the data arrays to be plotted. However, you may also create the cursor objects using this cursor 'init' call after creating a figure on your own (i.e. without using the plt pseudo object).

Ret1 = cur(axis,'init',In1,In2,In3,In4,In5,In6,In7,In8,In9);

where:

Notes:

When the cur('init' function is called, plt will attempt to add cursors to all lines of the axis created by plt. If you want plt to skip adding cursors to some of the lines, you should tag the line with the string 'SkipCur'. For example, a cursor would not be created for a line created with the following command: line(x,y,'tag','SkipCur');
  Another way to restrict which lines are to be cursored is to add the application data key 'Lhandles' to the axis. (For example: setappdata(ax,'Lhandles',[h1 h3]); would tell the cursor initialization routine to add cursors only to those two handles.)